package org.yunai.swjg.server.module.item.template;


import org.jumpmind.symmetric.csv.CsvReader;
import org.yunai.swjg.server.module.currency.Currency;
import org.yunai.swjg.server.module.item.ItemDef;
import org.yunai.yfserver.util.CsvUtil;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 道具模版基类
 * User: yunai
 * Date: 13-4-6
 * Time: 下午2:29
 */
public abstract class ItemTemplate {
    /**
     * 道具编号
     */
    private int id;
    /**
     * 道具名称
     */
    private String name;
    /**
     * 品质
     */
    private ItemDef.Quality quality;
    /**
     * 道具身份类型<br />
     * 一级属性
     */
    private ItemDef.IdentityType identityType;
    /**
     * 道具类型<br />
     * 二级属性
     */
    private ItemDef.Type type;
    /**
     * 描述
     */
    private String desc;
    /**
     * 使用等级
     */
    private int needLevel;
    /**
     * 出售货币ID
     */
    private Currency sellCurrency;
    /**
     * 出售价格
     */
    private int sellPrice;
    /**
     * 是否可出售
     */
    private boolean canSell;
    /**
     * 是否可丢弃
     */
    private boolean canDiscard;
    /**
     * 是否可使用
     */
    private boolean canUse;
    /**
     * 最大堆叠数量
     */
    private int maxOverlap;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public ItemDef.Quality getQuality() {
        return quality;
    }

    public ItemDef.IdentityType getIdentityType() {
        return identityType;
    }

    public ItemDef.Type getType() {
        return type;
    }

    public String getDesc() {
        return desc;
    }

    public int getNeedLevel() {
        return needLevel;
    }

    public Currency getSellCurrency() {
        return sellCurrency;
    }

    public int getSellPrice() {
        return sellPrice;
    }

    public boolean isCanSell() {
        return canSell;
    }

    public boolean isCanDiscard() {
        return canDiscard;
    }

    public boolean isCanUse() {
        return canUse;
    }

    public int getMaxOverlap() {
        return maxOverlap;
    }

    public boolean canOverlap() {
        return this.maxOverlap > 1;
    }

    // ==================== 非set/get方法 ====================
    private static Map<Integer, ItemTemplate> templates;

    public static ItemTemplate getItemTemplate(Integer id) {
        return templates.get(id);
    }

    /**
     * 根据道具名获得道具模版<br />
     * 该方法仅仅是为了导出模版时使用，业务逻辑里请勿调用
     *
     * @param name 道具名
     * @return 道具模版
     */
    public static ItemTemplate getItemTemplate(String name) {
        for (ItemTemplate template : templates.values()) {
            if (template.getName().equals(name)) {
                return template;
            }
        }
        return null;
    }

    public static void load() {
        CsvReader reader = null;
        // 道具公用模板
        templates = new HashMap<>();
        try {
            reader = CsvUtil.createReader("csv/item/item_template.csv");
            reader.readHeaders();
            while (reader.readRecord()) {
                ItemTemplate template = genItemTemplate(reader);
                templates.put(template.getId(), template);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        // 继续加载
        genItemTemplateThen("csv/item/item_template_consumable.csv");
        genItemTemplateThen("csv/item/item_template_equipment.csv");
        genItemTemplateThen("csv/item/item_template_material.csv");
        genItemTemplateThen("csv/item/item_template_reel.csv");
    }

    private static ItemTemplate genItemTemplate(CsvReader reader) throws IOException {
        Integer id = CsvUtil.getInt(reader, "id", 0);
        ItemDef.IdentityType identityType = ItemDef.IdentityType.valueOf(CsvUtil.getInt(reader, "identityType", 0));
        ItemTemplate template = null;
        switch (identityType) {
            case EQUIPMENT:
                template = new EquipmentItemTemplate();
                break;
            case MATERIAL:
                template = new MaterialItemTemplate();
                break;
            case REEL:
                template = new ReelItemTemplate();
                break;
            case CONSUMABLE:
                template = new ConsumableItemTemplate();
                break;
        }
        template.id = id;
        template.name = CsvUtil.getString(reader, "name", "");
        template.quality = ItemDef.Quality.valueOf(CsvUtil.getShort(reader, "quality", (short) 0));
        template.identityType = identityType;
        template.type = ItemDef.Type.valueOf(CsvUtil.getInt(reader, "type", 0));
        template.desc = CsvUtil.getString(reader, "desc", "");
        template.needLevel = CsvUtil.getInt(reader, "needLevel", 0);
        template.sellCurrency = Currency.valueOf(CsvUtil.getInt(reader, "sellCurrency", 0));
        template.sellPrice = CsvUtil.getInt(reader, "sellPrice", 0);
        template.canSell = "1".equals(CsvUtil.getString(reader, "canSell", ""));
        template.canDiscard = "1".equals(CsvUtil.getString(reader, "canDiscard", ""));
        template.canUse = "1".equals(CsvUtil.getString(reader, "canUse", ""));
        template.maxOverlap = CsvUtil.getInt(reader, "maxOverlap", 0);
        return template;
    }

    private static void genItemTemplateThen(String file) {
        CsvReader reader = null;
        try {
            reader = CsvUtil.createReader(file);
            reader.readHeaders();
            while (reader.readRecord()) {
                Integer id = Integer.valueOf(reader.get("id"));
                ItemTemplate template = templates.get(id);
                template.genTemplate(reader);
                template.check();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }

    @SuppressWarnings("unchecked")
    public static <T extends ItemTemplate> T getItemTemplate(Integer id, Class<T> clazz) {
        return (T) templates.get(id);
    }

    public static boolean isEqual(ItemTemplate templateA, Integer templateIdB) {
        return templateA != null && isEqual(templateA.getId(), templateIdB);
    }

    public static boolean isEqual(ItemTemplate templateA, ItemTemplate templateB) {
        return !(templateA == null || templateB == null) && isEqual(templateA.getId(), templateB.getId());
    }

    public static boolean isEqual(Integer templateIdA, Integer templateIdB) {
        return !(templateIdA == null || templateIdB == null) && templateIdA.equals(templateIdB);
    }

    /**
     * 加载完道具基本字段，再进一步加载子类
     *
     * @param reader   CSV读取
     */
    protected abstract void genTemplate(CsvReader reader) throws IOException;

    /**
     * 做模版的检查
     */
    protected abstract void check();
}